package com.example.easybuy.interceptor;

import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.example.easybuy.annotaion.CheckPermission;
import com.example.easybuy.entity.User;
import com.example.easybuy.exception.CheckTokenException;
import com.example.easybuy.exception.LoginTimeOutException;
import com.example.easybuy.exception.NoLoginException;
import com.example.easybuy.exception.PermissionException;
import com.example.easybuy.service.UserService;
import com.example.easybuy.util.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Component
public class UserCheckInterceptor implements HandlerInterceptor {
    public static final Logger log = LoggerFactory.getLogger(UserCheckInterceptor.class);

    private StringRedisTemplate redisTemplate;
    private UserService userService;

    @Autowired
    public UserCheckInterceptor(StringRedisTemplate redisTemplate, UserService userService) {
        this.redisTemplate = redisTemplate;
        this.userService = userService;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("请求地址：" + request.getRequestURI());
        String token = request.getHeader("Authorization");
        log.info("token" + token);
        //验证是否登录
        if (token == null || token.isEmpty()) {
            throw new NoLoginException();
        }
        //验证token
        String loginName = null;
        try {
            loginName = JwtUtil.getLoginName(token);
        } catch (SignatureVerificationException e) {
            throw new CheckTokenException();
        } catch (TokenExpiredException e) {
            throw new LoginTimeOutException();
        }

        String serverToken = redisTemplate.opsForValue().get(loginName);
        if (serverToken == null || !token.equals(serverToken)) {
            throw new CheckTokenException();
        }

        //token延期
        Date exp = JwtUtil.getExpires(token);
        if (exp.getTime() - System.currentTimeMillis() < 5 * 60 * 100) {
            //进行token置换
            String newToken = JwtUtil.createToken(loginName);
            redisTemplate.opsForValue().set(loginName, newToken, 30, TimeUnit.MINUTES);
            response.setHeader("Access-Control-Expose-Headers", "x-token");
            response.setHeader("x-token", newToken);
        }

        //验证权限
        boolean isHandlerMethod = handler instanceof HandlerMethod;
        if (!isHandlerMethod) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        CheckPermission checkPermission = handlerMethod.getMethodAnnotation(CheckPermission.class);
        if (checkPermission == null) {
            return true;
        }
        String[] roles = checkPermission.value();
        if (checkRole(loginName, roles)) {
            return true;
        } else {
            throw new PermissionException();
        }
    }

    public boolean checkRole(String loginName, String[] roles) {
        User user = userService.findUser(loginName);
        for (String role : roles) {
            if (role.equals(user.getType() + "")) {
                return true;
            }
        }
        return false;
    }
}